package main

import (
	"fmt"
	"unsafe"
)

func main() {
	/*
		类型	     名称	长度	 零值	说明
		bool	布尔类型	1	false	其值不为真即为假，不可以用数字代表true或false
		byte	字节型	1	 0	    uint8别名
		rune	字符类型	4	 0	    专用于存储unicode编码，等价于uint32
		int, uint 整型	4或8  0	    32位或64位
		int8, uint8	整型	1	  0	     -128 ~ 127, 0 ~ 255
		int16, uint16	整型	2 0	    -32768 ~ 32767, 0 ~ 65535
		int32, uint32	整型	4 0	    -21亿~ 21亿, 0 ~ 42亿
		int64, uint64	整型	8 0
		float32	浮点型	4	0.0	小数位精确到7位
		float64	浮点型	 8	0.0	小数位精确到15位
		complex64 复数类型	8
		complex128 复数类型	16
		uintptr	整型	4或8		⾜以存储指针的uint32或uint64整数
		string	字符串		“”	utf-8字符串
	*/
	//bool	布尔类型	1	false	其值不为真即为假，不可以用数字代表true或false
	var a bool
	fmt.Println(a)
	a = true
	fmt.Println(a)
	//布尔类型不接受其他类型的赋值，不支持自动或强制的类型转换
	//a=bool(1)
	//fmt.Println(a)   //报错
	//int, uint 整型	4或8  0	    32位或64位
	//1.int是有符号整型 uint是无符号整型
	var c int = 20
	fmt.Println(c)
	//在64位电脑内存中占用的大小
	fmt.Println(unsafe.Sizeof(c))
	//字符类型
	//1.单引号表示字符 双引号表示字符串
	var d byte = 'd'
	fmt.Println("d=", d)
	//%c是一个占位符，表示打印一个字符
	fmt.Printf("%c", d)
	//byte也是uint8的别名
	fmt.Printf("%T\n", d)
	//string	字符串		“”	utf-8字符串
	ca := "无聊啊"
	fmt.Println(ca)
	fmt.Printf("%T\n", ca)
	//len函数 计算字符串中字符的个数，不包含\0
	//在go语言中，一个汉字占3个字符
	fmt.Println(len(ca))
	//字符串拼接
	ca1 := "龙猫"
	ca2 := "夏露露"
	ca3 := ca1 + ca2
	fmt.Println(ca3)
	//字符和字符串的区别
	//双引号为字符串，单引号是字符
	//字符串都是隐藏了一个结束符"\0"
	str := "hello"
	fmt.Println(str)
	fmt.Println(str[0], str[1])
	fmt.Printf("%c%c\n", str[0], str[1])
	//复数类型
	//复数实际上由两个实数（在计算机中用浮点数表示）构成，一个表示实部（real），一个表示虚部（imag）
	//支持自动推导
	//默认为complex128
	t1 := 3.4 + 12.4i
	fmt.Println(t1)
	//通过real(t1)获取实数，imag(t1)获取虚数
	fmt.Println(real(t1), imag(t1))
	/*
		格式	   含义
		%%	一个%字面量
		%b	一个二进制整数值(基数为2)，或者是一个(高级的)用科学计数法表示的指数为2的浮点数
		%c	字符型。可以把输入的数字按照ASCII码相应转换为对应的字符
		%d	一个十进制数值(基数为10)
		%e	以科学记数法e表示的浮点数或者复数值
		%E	以科学记数法E表示的浮点数或者复数值
		%f	以标准记数法表示的浮点数或者复数值
		%g	以%e或者%f表示的浮点数或者复数，任何一个都以最为紧凑的方式输出
		%G	以%E或者%f表示的浮点数或者复数，任何一个都以最为紧凑的方式输出
		%o	一个以八进制表示的数字(基数为8)
		%p	以十六进制(基数为16)表示的一个值的地址，前缀为0x,字母使用小写的a-f表示
		%q	使用Go语法以及必须时使用转义，以双引号括起来的字符串或者字节切片[]byte，或者是以单引号括起来的数字
		%s	字符串。输出字符串中的字符直至字符串中的空字符（字符串以’\0‘结尾，这个’\0’即空字符）
		%t	以true或者false输出的布尔值
		%T	使用Go语法输出的值的类型
		%U	一个用Unicode表示法表示的整型码点，默认值为4个数字字符
		%v	使用默认格式输出的内置或者自定义类型的值，或者是使用其类型的String()方式输出的自定义值，如果该方法存在的话
		%x	以十六进制表示的整型值(基数为十六)，数字a-f使用小写表示
		%X	以十六进制表示的整型值(基数为十六)，数字A-F使用小写表示
	*/
	//fmt格式化输出
	//%T 打印变量所属数据类型
	a11 := 10
	a22 := "ssss"
	a33 := 3.122
	fmt.Printf("%T\n", a11)
	//%d 整型格式
	fmt.Printf("%d\n", a11)
	//%s 字符串输出
	fmt.Printf("%s\n", a22)
	//%c字符输出
	//%f 浮点输出 如果想保留2位小数在f前加.2 以此类推
	fmt.Printf("%.2f\n", a33)
	//%v 自动匹配格式化输出
	fmt.Printf("%v\n", a33)
	//输入
	//var name string
	//fmt.Printf("请输入：")
	//fmt.Scan(&name)
	//fmt.Println("输入的结果是",name)
	//类型转换
	a44, a55, m := 20, 30, 40
	sum := a44 + a55 + m
	fmt.Println(float64(sum) / 3)
	//在类型转换中，建议低类型转换成高类型，保证数据的精度
	/*
		类型别名
	*/
	//使用type关键字给int64 起一个为 shuzu的别名
	type shuzu int64
	var na shuzu = 10
	fmt.Println(na)

	/*
		运算符	术语	示例		结果
			+	加	10 + 5	15
			-	减	10 - 5	5
			*	乘	10 * 5	50
			/	除	10 / 5	2
			%	取模(取余)	10 % 3	1
			++	后自增，没有前自增	a=0; a++	a=1
			–	后自减，没有前自减	a=2; a–	a=1
	*/
	//++和--
	jia := 10
	fmt.Println("没有自增", jia)
	jia++
	fmt.Println(jia)
	/*
		运算符	术语	示例		结果
		==	相等于	4 == 3	false
		!=	不等于	4 != 3	true
		<		小于	4 < 3	false
		>		大于	4 > 3	true
		< =	小于等于	4 < = 3	false
		>=	大于等于	4 >= 1	true
		关系运算符常用于判断语句当中

	*/
	//关系运算符
	//var v string //用于接收用户密码的变量
	//var t string="123456" //自己定义的密码
	//fmt.Scan(&v) //用户传入一个密码。
	//if(v != t){
	//	fmt.Println("您输入的密码错误");
	//}
	/*
		运算符	术语		示例		结果
		!		非		!a		如果a为假，则!a为真；如果a为真，则!a为假。
		&&		与		a && b	如果a和b都为真，则结果为真，否则为假。
		||		或		a || b	如果a和b有一个为真，则结果为真，二者都为假时，结果为假
		&	取地址运算符	&a		变量a的地址
		*	取值运算符	*a		指针变量a所指向内存的值
	*/
	//&&
	//用登录作为案例：
	//登录条件需要，一个用户名，还有一个用户密码
	//我首先自己定义一下用户名和密码

	var use int = 777     //自己定义的用户名
	var userpwd int = 123 //自己定义的密码

	var a66 int = 777 //假设用户输入的用户名
	var b66 int = 456 //假设用户输入的密码

	//我们先拿用户名作为比较，username==a,这里是不是一样的值，所以这个返回是true
	//然后我再来对比密码,userpwd==b,这里的值是不一样的，所以这个返回是false
	//那么我们把他连起来呢？

	b77 := use == a66 && userpwd == b66

	//其中是不是有一个true和一个false
	//&&的作用就是只要这两个判断中有一个为false就会返回false
	//必须两个都为true才回返回true
	//也就是说你用户名虽然对了，但是你密码不对你还是登不上去
	//反之只有你用户名和密码都对了才能登陆
	fmt.Println(b77)
	//||
	//拿身份证取票乘车作为比较，我们坐车要有车票网上买的车票是不是要取票，取票就需要把身份证刷一下，
	//如果你忘记带身份证了那就可以去办个临时身份证，也是一样可以取票的 例如：
	var a88 int = 2 //身份证等于2的原因是假设我没带身份证
	var b88 int = 1 //临时身份证

	//假设取票必须等于1
	var c88 int = 1 //取票必须值一样
	//首先我们a==c吗？很明显是不等于的，那么返回值就是false
	//再来b==c吗？验证结果是相等的，办的临时身份证也是可以取票的，那么返回值就是true
	//那么我们连起来

	b11 := a88 == c88 || b88 == c88
	//"||"的作用就是只要你这两个条件之中有一个为true他就给你返回true
	//就算你有一个条件是false他也是不予理睬的还是会算你通过
	//也就是说，你没带身份证没关系办个临时的也能用
	fmt.Println("取票值=", b11)
	//&
	//取址符，就像变量刚创建出来就会放在内存里面，我们用&就能查到它在内存中的位置例如:

	a111 := 55
	fmt.Printf("%p\n", &a111)  //就能打印出内存地址了
	fmt.Printf("%d\n", *&a111) //为什么要加&号呢？首先我们要找到a变量在内存中的地址

}
